/*
 * Copyright (c) 2020. bmy
 * Email：2271608011@qq.com
 * Github：https://github.com/helpcode
 */

const isProduction = process.env.NODE_ENV === 'production';
// const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const CompressionPlugin = require('compression-webpack-plugin')
const path = require('path');
const { ProgressPlugin } = require("webpack")
const chalk = require("chalk");

let js = [
  'https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js',
  'https://cdn.bootcdn.net/ajax/libs/vuex/3.5.1/vuex.min.js',
  'https://cdn.bootcdn.net/ajax/libs/vue-router/3.2.0/vue-router.min.js',
  'https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js',
  'https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.2/index.min.js'
]

let exclude = {
  'vue': 'Vue',
  'vuex': 'Vuex',
  'vue-router': 'VueRouter',
  'axios': 'axios',
  'element-ui': 'ELEMENT'
}

module.exports = {
  publicPath: './',
  filenameHashing: true,
  productionSourceMap: false,
  parallel: require('os').cpus().length > 1,
  lintOnSave: false,
  pluginOptions: {
    route: {
      // 默认：page。存放Vue路由页面的文件夹名称
      TemplateFolderName: 'page',
      // 默认：./src/application。从src/开始到TemplateFolderName文件夹父一级文件夹相对路径
      RootFolderName: './src/application',
      // 默认 src/core/config/route.config.ts。生成的配置文件保存路径，相对插件的位置来。
      SaveConfigPath: '../../../src/core/config/route.config.ts'
    }
  },
  devServer: {
    hot: true,
    port: 8080,
    compress: false,
    open: false,
    openPage: '#/Home',
    progress: false,
    overlay: {
      warnings: false,
      errors: true
    },
    // before 这块代码都可以删除，仅仅为脚手架提供一个用于测试的接口
    before: function (app, server) {
      app.all('*', function (req, res, next) {
        res.header('Access-Control-Allow-Origin', '*');
        res.header('Access-Control-Allow-Headers', '*');
        res.header('Access-Control-Allow-Methods', '*');
        res.header('Content-Type', 'application/json;charset=utf-8');
        next();
      });
      app.get('/UserList', function (req, res) {
        res.json({
          status: 200,
          message: '请求成功',
          result: [
            { id: 1, name: '张三' },
            { id: 2, name: '李四' }
          ]
        });
      });
    },
    // proxy: {
    //   '/api': {
    //     target: 'http://115.159.153.142:9010/h5',
    //     changeOrigin: true,
    //     ws: true,
    //     pathRewrite: {
    //       '^/api': ''
    //     }
    //   }
    // }
  },
  configureWebpack: config => {
    // 设置程序核心入口
    config.entry.app = ['babel-polyfill', './src/core/run/init.run.ts'];

    if (isProduction) {
      // 需要被打包排除的插件列表
      config.externals = exclude

      // 开启 Gzip压缩
      return {
        plugins: [
          new BundleAnalyzerPlugin(),

          // new CompressionPlugin({
          //   test: /\.js$|\.html$|\.css/, //匹配文件名
          //   threshold: 10240, //对超过10k的数据进行压缩
          //   deleteOriginalAssets: false //是否删除原文件
          // })
        ]
      };
    } else {
      return {
        plugins: [
          new ProgressPlugin({
            handler: (percentage, message, ...args) => {
              console.log(`${chalk.yellow("进度: ")}${chalk.green.bold(~~(percentage * 100) + "%")} ${args[0] ? chalk.black(args[0]) : " " } ${chalk.blue.bold(message)}`)
            },
          })
        ]
      }
    }
  },
  chainWebpack: (config) => {
    if (isProduction) {
      // 去除混淆加密
      config.optimization.minimize(false)

      // 移除 prefetch，preload 插件 减少不必要的请求
      config.plugins.delete('prefetch')
      config.plugins.delete('preload')

      // 生产环境下注入一个变量cdn 变量可以在html中通过htmlWebpackPlugin.options进行获取
      config.plugin('html')
        .tap(args => {
          args[0].cdn = js;
          return args;
        })
    }

    /**
     * 配置路径别名，项目中引用资源的时候路径可以更简短
     * 但是ts文件在用的时候，编译器会报错，需要添加 @ts-ignore
     * 忽略开发工具的错误。
     */
    config.resolve.alias
      .set('@', resolve('src'))
      .set('@core', resolve('src/core'))
      .set('@router', resolve('src/core/router'))
      .set('@store', resolve('src/core/store'))
      .set('@types', resolve('src/core/types'))
      .set('@config', resolve('src/core/config'))
      .set('@utils', resolve('src/core/utils'))
      .set('@run', resolve('src/core/run'))
      .set('@ann', resolve('src/core/annotation'))
      .set('@model', resolve('src/core/model'))
      .set('@dao', resolve('src/core/dao'))
      .set('@entity', resolve('src/core/entity'))
      .set('@service', resolve('src/core/service'))
      .set('@impl', resolve('src/core/service/impl'))

      .set('@application', resolve('src/application'))
      .set('@img', resolve('src/application/assets/img'))
      .set('@less', resolve('src/application/assets/less'))
      .set('@pageLess', resolve('src/application/assets/less/page'))
      .set('@componentsLess', resolve('src/application/assets/less/components'))
      .set('@components', resolve('src/application/components'))
      .set('@page', resolve('src/application/page'))
      .set('@logic', resolve('src/application/logic'))
      .set('@layout', resolve('src/application/layout'))
  }

};

function resolve(dir) {
  return path.join(__dirname, dir);
}
